//
//  ACDiskCache.h
//  ACCache_Example
//
//  Created by autohome on 2021/8/7.
//  Copyright © 2021 CaiXiang. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "ACORMObjectProtocol.h"

NS_ASSUME_NONNULL_BEGIN

@interface ACDiskCache : NSObject

- (BOOL)containsObjectForKey:(NSString *)key;
- (nullable id<NSCoding>)objectForKey:(NSString *)key;
- (void)setObject:(nullable id<NSCoding>)object forKey:(NSString *)key;
- (void)removeObjectForKey:(NSString *)key;
- (void)removeAllObjects;

/*!
 @property
 @abstract 缓存有效时长，单位秒
 */
@property (atomic, assign) NSTimeInterval effectiveCacheTime;
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
/// 初始化构造方法
/// @param dbPath 路径
- (nullable instancetype)initWithPath:(NSString *)path;
/// 往数据库中增加一条数据<不开启事务>
/// @param object <需要遵守ACORMObjectProtocol>
- (BOOL)insertObject:(id<ACORMObjectProtocol>)object;
/// 往数据库中增加一条数据<不开启事务>
/// @param object <需要遵守ACORMObjectProtocol>
/// @param tableName 数据表名,传nil则默认表明为类名
- (BOOL)insertObject:(id<ACORMObjectProtocol>)object
                into:(NSString *)tableName;

/// 往数据库中增加一组数据<不开启事务>
/// @param objects <需要遵守ACORMObjectProtocol>
- (BOOL)insertObjects:(NSArray<id<ACORMObjectProtocol>> *)objects;

/// 往数据库中增加一组数据<不开启事务>
/// @param objects <需要遵守ACORMObjectProtocol>
/// @param tableName 数据表名,传nil则默认表明为类名
- (BOOL)insertObjects:(NSArray<id<ACORMObjectProtocol>> *)objects
                 into:(NSString *)tableName;

/// 往数据库中增加一组数据,开始事务.
/// @param objects <需要遵守ACORMObjectProtocol>
/// @param tableName 数据表名,传nil则默认表明为类名
- (BOOL)insertObjectsInTransaction:(NSArray<id<ACORMObjectProtocol>> *)objects
                              into:(NSString*)tableName;

/// 往数据库中增加或修改一条数据<不开启事务>
/// @param object <需要遵守ACORMObjectProtocol>
/// @param tableName 数据表名,传nil则默认表明为类名
- (BOOL)insertOrReplaceObject:(id<ACORMObjectProtocol>)object
                         into:(NSString *)tableName;

/// 往数据库中增加或修改一组数据<不开启事务>
/// @param objects <需要遵守ACORMObjectProtocol>
/// @param tableName 数据表名,传nil则默认表明为类名
- (BOOL)insertOrReplaceObjects:(NSArray<id<ACORMObjectProtocol>> *)objects
                          into:(NSString *)tableName;

/// 往数据库中增加或修改一组数据<开启事务>
/// @param objects <需要遵守ACORMObjectProtocol>
/// @param tableName 数据表名,传nil则默认表明为类名
- (BOOL)insertOrReplaceObjectsInTransaction:(NSArray<id<ACORMObjectProtocol>> *)objects
                              into:(NSString*)tableName;

/// 更新数据
/// @breif: 使用第一种或者不传tableName 则默认使用类名作为表名.
/// @param clazz 需要更新的模型Class
/// @param keyValues 需要更新的字段键值对 <key:属性名 value:需要更新的值>
/// @param predicateFormat 格式化查询条件.
/// @example :[...xxxcond:@"dataID = '%@ AND id=%d'",dataID, id]
- (BOOL)updateObjectClazz:(Class)clazz keyValues:(NSDictionary *)keyValues cond:(NSString *)predicateFormat,...;
- (BOOL)updateTableName:(NSString*)tableName objectClazz:(Class)clazz keyValues:(NSDictionary *)keyValues cond:(NSString *)predicateFormat,...;

/**
 获取数据表中的全部数据
 @breif:使用第一种或者不传tableName 则默认使用类名作为表名.
 @param clazz 需要查询的模型Class
 @return class表的全部数据
 */
- (NSArray*)getAllObjectsWithClass:(Class)clazz;
- (NSArray*)getAllObjectsWithClass:(Class)clazz withTableName:(NSString*)tableName;

/**
 根据condition获取数据表中符合条件的数据
 @breif:使用第一种或者不传tableName 则默认使用类名作为表名.
 @param clazz 需要查询的模型Class
 @param predicateFormat 格式化查询条件.
        orderName 排序的propertyName 降序 需要在propertyName后拼接 'desc'
        limit 传0无限制.
        CustomCond:默认不拼接'where',condition 自定义 "where dataID='AAA' order by dataID limit 10"
 @example:[...xxxcond:@"dataID = '%@ AND id=%d'",dataID, id]
 @return 数据表中符合条件的所有数据集合
 */
- (NSArray *)getObjectsWithClass:(Class)clazz whereCond:(NSString *)predicateFormat, ...;
- (NSArray *)getObjectsWithClass:(Class)clazz withTableName:(NSString*)tableName whereCond:(NSString *)predicateFormat, ...;
- (NSArray *)getObjectsWithClass:(Class)clazz withTableName:(NSString*)tableName CustomCond:(NSString *)predicateFormat, ...;
- (NSArray *)getObjectsWithClass:(Class)clazz withTableName:(NSString*)tableName orderBy:(NSString*)orderName limit:(NSInteger)count cond:(NSString *)predicateFormat, ...;
/**
 根据condition 获取数据表中符合条件的数据集合,直接返回字典数据

 @param tableName 表名
 @param predicateFormat 查询条件.如果传'nil'查询全部
 @return 返回字典数组.
 */
- (NSArray *)getResultDictionaryWithTableName:(NSString*)tableName CustomCond:(NSString *)predicateFormat, ...;
/**
 删除数据表

 @param clazz 如果表名为class 可使用第一种
 @return YES/NO
 */
- (BOOL)removeTableWithClass:(Class)clazz;
- (BOOL)removeTable:(NSString*)table_name;

@end

NS_ASSUME_NONNULL_END
